package com.niiwoo.civet.account.service.local.bill;

import com.niiwoo.civet.account.dao.entity.NiiwooBillGuarantee;
import com.niiwoo.civet.account.dao.entity.NiiwooBillGuaranteeExample;
import com.niiwoo.civet.account.dao.entity.NiiwooBillGuaranteeExampleExt;
import com.niiwoo.civet.account.dao.mapper.NiiwooBillGuaranteeMapper;
import com.niiwoo.civet.account.dao.mapper.NiiwooBillGuaranteeMapperExt;
import com.niiwoo.civet.account.dto.bill.BillBase;
import com.niiwoo.civet.account.dto.request.GuaranteeBillQueryRequest;
import com.niiwoo.civet.account.enums.BillDateReleatedTypeEnum;
import com.niiwoo.civet.account.enums.BillSecondSubjectEnum;
import com.niiwoo.civet.account.enums.BillStatusEnum;
import com.niiwoo.civet.account.enums.OrderTypeEnum;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.FastDateFormat;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;


/**
 * 担保机构的账单Service
 *
 * @author xiaoyingping
 * @create 2017-11-20 10:06
 **/
@Service
@Slf4j
public class NiiwooBillGuaranteeService {
    @Autowired
    private NiiwooBillGuaranteeMapper niiwooBillGuaranteeMapper;
    @Autowired
    private NiiwooBillGuaranteeMapperExt niiwooBillGuaranteeMapperExt;
    @Autowired
    private BillDateReleatedService billDateReleatedService;
    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;


    /**
     * 新增担保机构账单
     *
     * @param niiwooBillGuarantee
     * @return
     */
    public Integer addNiiwooBillGuarantee(BillBase billBase, NiiwooBillGuarantee niiwooBillGuarantee) {
        niiwooBillGuarantee.setBillId(snowflakeIdWorker.nextId());
        niiwooBillGuarantee.setBillBaseId(billBase.getId());
        niiwooBillGuarantee.setGuaranteeOrgId(billBase.getUserId());
        niiwooBillGuarantee.setAccountId(billBase.getAccountId());
        niiwooBillGuarantee.setInvestId(billBase.getInvestId());
        niiwooBillGuarantee.setGuaranteeId(billBase.getGuaranteeId());
        niiwooBillGuarantee.setOrderId(billBase.getOrderId());
        niiwooBillGuarantee.setOrderType(billBase.getOrderType());
        niiwooBillGuarantee.setStatus(billBase.getStatus());
        niiwooBillGuarantee.setCreateTime(billBase.getCreateTime());
        niiwooBillGuarantee.setUpdateTime(billBase.getUpdateTime());

        DateTime createTime = new DateTime(billBase.getCreateTime());
        niiwooBillGuarantee.setYearMonth(createTime.toString("yyyyMM"));
        niiwooBillGuarantee.setYearMonthDay(createTime.toString("yyyy-MM-dd"));

        BillSecondSubjectEnum secondSubjectEnum = BillSecondSubjectEnum.getEnumByCode(niiwooBillGuarantee.getSecondSortCode());
        niiwooBillGuarantee.setFirstSortCode(secondSubjectEnum.getFirstSubject().getCode());
        niiwooBillGuarantee.setInoutType(secondSubjectEnum.getFirstSubject().getInOutType());

        billDateReleatedService.addBillDateReleated(niiwooBillGuarantee);
        return niiwooBillGuaranteeMapper.insertSelective(niiwooBillGuarantee);
    }

    /**
     * 修改账单状态：通过订单ID和订单类型
     * @param orderId
     * @param orderType
     * @param statusEnum
     * @return
     */
    public int updateBillStatusByOrderId(String orderId, OrderTypeEnum orderType, BillStatusEnum statusEnum) {
        Assert.hasLength(orderId, "orderId不能为空");
        Assert.notNull(orderType, "orderType不能为空");

        List<String> yearMonthDay = billDateReleatedService.queryBillDates(BillDateReleatedTypeEnum.ORDER_ID, orderId);

        NiiwooBillGuaranteeExample example = new NiiwooBillGuaranteeExample();
        NiiwooBillGuaranteeExample.Criteria criteria = example.createCriteria();
        criteria.andOrderIdEqualTo(orderId);
        criteria.andOrderTypeEqualTo(orderType.getCode());
        if(!CollectionUtils.isEmpty(yearMonthDay)){
            criteria.andYearMonthDayIn(yearMonthDay);
        }

        NiiwooBillGuarantee niiwooBillGuarantee = new NiiwooBillGuarantee();
        niiwooBillGuarantee.setStatus(statusEnum.getValue());
        niiwooBillGuarantee.setUpdateTime(new Date());
        return niiwooBillGuaranteeMapper.updateByExampleSelective(niiwooBillGuarantee, example);
    }

    /**
     * 查询担保账单列表
     *
     * @param billQueryRequest
     * @return
     */
    public List<NiiwooBillGuarantee> pageGuaranteeBills(GuaranteeBillQueryRequest billQueryRequest) {

        NiiwooBillGuaranteeExampleExt example = generateGuaranteeBillExample(billQueryRequest);
        if (null == example) {
            return Collections.EMPTY_LIST;
        }

        Integer offset = billQueryRequest.getOffset();
        Integer pageSize = billQueryRequest.getPageSize();
        Assert.notNull(offset, "offset不能为空");
        Assert.notNull(pageSize, "pageSize不能为0");
        example.setOffset(offset);
        example.setPageSize(pageSize);
        example.setOrderByClause("create_time desc");

        return niiwooBillGuaranteeMapperExt.pageByExample(example);
    }
    /**
     * 查询担保账单列表(不分页)
     *
     * @param billQueryRequest
     * @return
     */
    public List<NiiwooBillGuarantee> listGuaranteeBills(GuaranteeBillQueryRequest billQueryRequest) {
        NiiwooBillGuaranteeExampleExt example = generateGuaranteeBillExample(billQueryRequest);
        if (null == example) {
            return Collections.EMPTY_LIST;
        }
        example.setOrderByClause("create_time desc");
        return niiwooBillGuaranteeMapper.selectByExample(example);

    }

    /**
     * 查询账单列表：通过订单ID和订单类型
     * @param orderId
     * @param orderType
     * @return
     */
    public List<NiiwooBillGuarantee> getByOrderIdAndType(String guaranteeOrgId, String orderId, OrderTypeEnum orderType){
        Assert.hasLength(guaranteeOrgId, "guaranteeOrgId不能为空");
        Assert.hasLength(orderId, "orderId不能为空");
        Assert.notNull(orderType, "orderType不能为空");

        //查询日期
        List<String> yearMonthDay = billDateReleatedService.queryBillDates(BillDateReleatedTypeEnum.ORDER_ID, orderId);

        NiiwooBillGuaranteeExample example = new NiiwooBillGuaranteeExample();
        NiiwooBillGuaranteeExample.Criteria criteria = example.createCriteria();
        criteria.andGuaranteeOrgIdEqualTo(guaranteeOrgId);
        criteria.andOrderIdEqualTo(orderId);
        criteria.andOrderTypeEqualTo(orderType.getCode());
        if(!CollectionUtils.isEmpty(yearMonthDay)){
            criteria.andYearMonthDayIn(yearMonthDay);
        }

        return niiwooBillGuaranteeMapper.selectByExample(example);
    }

    /**
     * 统计账单数量
     *
     * @param billQueryRequest
     * @return
     */
    public Long countPlatformBills(GuaranteeBillQueryRequest billQueryRequest) {
        NiiwooBillGuaranteeExample example = generateGuaranteeBillExample(billQueryRequest);
        if (null == example) {
            return 0L;
        }

        return niiwooBillGuaranteeMapper.countByExample(example);
    }

    private NiiwooBillGuaranteeExampleExt generateGuaranteeBillExample(GuaranteeBillQueryRequest billQueryRequest) {
        Assert.notNull(billQueryRequest, "billQueryRequest不能为空");
        NiiwooBillGuaranteeExampleExt example = new NiiwooBillGuaranteeExampleExt();
        NiiwooBillGuaranteeExampleExt.Criteria criteria = example.createCriteria();

        boolean haveSharding = false;
        Date startCreateDate = billQueryRequest.getStartCreateDate();
        Date endCreateDate = billQueryRequest.getEndCreateDate();
        if (Objects.nonNull(startCreateDate) && Objects.nonNull(endCreateDate)) {
            haveSharding = true;

            String startYearMonthDay = FastDateFormat.getInstance("yyyy-MM-dd").format(startCreateDate);
            String endYearMonthDay = FastDateFormat.getInstance("yyyy-MM-dd").format(endCreateDate);
            criteria.andYearMonthDayBetween(startYearMonthDay, endYearMonthDay);
            criteria.andCreateTimeBetween(startCreateDate, endCreateDate);
        }


        if (Objects.nonNull(billQueryRequest.getProjectId())) {
            criteria.andProjectIdEqualTo(billQueryRequest.getProjectId());

            List<String> billDateList = billDateReleatedService.queryBillDates(BillDateReleatedTypeEnum.PROJECT_ID, String.valueOf(billQueryRequest.getProjectId()));
            if (!CollectionUtils.isEmpty(billDateList)) {
                criteria.andYearMonthDayIn(billDateList);
                haveSharding = true;
            }
        }


        if (Objects.nonNull(billQueryRequest.getBillId())) {
            criteria.andBillIdEqualTo(billQueryRequest.getBillId());
        }
        if (Objects.nonNull(billQueryRequest.getRelationUserId())) {
            criteria.andRelationUserIdEqualTo(billQueryRequest.getRelationUserId());
        }
        //担保机构ID
        if (Objects.nonNull(billQueryRequest.getGuaranteeOrgId())) {
            criteria.andGuaranteeOrgIdEqualTo(billQueryRequest.getGuaranteeOrgId());
        }
        if (Objects.nonNull(billQueryRequest.getInoutType())) {
            criteria.andInoutTypeEqualTo(billQueryRequest.getInoutType().getType());
        }
        if (Objects.nonNull(billQueryRequest.getFirstSortCode())) {
            criteria.andFirstSortCodeEqualTo(billQueryRequest.getFirstSortCode());
        }
        if (Objects.nonNull(billQueryRequest.getSecondSortCode())) {
            criteria.andSecondSortCodeEqualTo(billQueryRequest.getSecondSortCode());
        }
        if (Objects.nonNull(billQueryRequest.getProjectType())) {
            criteria.andProjectTypeEqualTo(billQueryRequest.getProjectType());
        }
        if (Objects.nonNull(billQueryRequest.getChannelCode())) {
            criteria.andChannelCodeEqualTo(billQueryRequest.getChannelCode());
        }

        if (haveSharding) {
            return example;
        }
        return null;
    }

    /**
     * 根据baseId
     *
     * @param billBaseId
     * @param createTime 分表依据
     * @return
     */
    public List<NiiwooBillGuarantee> getCheckAccountBillsByBaseId(Long billBaseId, Date createTime) {
        Assert.notNull(createTime, "createTime不能为空");
        String yearMonthDay = new DateTime(createTime).toString("yyyy-MM-dd");

        NiiwooBillGuaranteeExample niiwooBillGuaranteeExample = new NiiwooBillGuaranteeExample();
        NiiwooBillGuaranteeExample.Criteria criteria = niiwooBillGuaranteeExample.createCriteria();
        criteria.andBillBaseIdEqualTo(billBaseId);
        criteria.andYearMonthDayEqualTo(yearMonthDay);
        return niiwooBillGuaranteeMapper.selectByExample(niiwooBillGuaranteeExample);
    }

    public List<NiiwooBillGuarantee> listByBaseId(Long billBaseId, String yearMonthDay){
        NiiwooBillGuaranteeExample example = new NiiwooBillGuaranteeExample();
        NiiwooBillGuaranteeExample.Criteria criteria = example.createCriteria();
        criteria.andBillBaseIdEqualTo(billBaseId);
        criteria.andYearMonthDayEqualTo(yearMonthDay);
        return niiwooBillGuaranteeMapper.selectByExample(example);
    }
}
